Note: This tutorial assumes a working knowledge of the Modelica language - for information on Modelica, please read this book: Modelica by Example. |
Please ask about problems and questions regarding this tutorial on answers.ros.org. Don't forget to include in your question the link to this page, the versions of your OS & ROS, and also add appropriate tags. |
Introduction to modelica_bridge
Description: This provides a brief overview of the modelica_bridge package, and an introductory explanation on usage.Keywords: Modelica, external c-functions, modelica_bridge, tcp/ip sockets
Tutorial Level: INTERMEDIATE
First Steps
Installation
modelica_bridge has been released for Ubuntu - to download the binary, paste and run the following command in the terminal:
sudo apt-get install ros-kinetic-modelica-bridge
To alternatively build from source, cd to the source subdirectory of your catkin workspace in terminal and run the following command:
git clone https://github.com/ModROS/modelica_bridge.git
Build using catkin_make as normal.
In order to use modelica_bridge effectively, it must used alongside its partner package in Modelica, the ROS_Bridge package. Download this from source:
git clone https://github.com/ModROS/ROS_Bridge.git ~/repos/ROS_Bridge
Basic Usage Instructions
The joint purpose of the modelica_bridge and ROS_Bridge packages is to provide interfaces to connect Modelica tools with the ROS system during simulation. The communication between Modelica and ROS is accomplished via TCP sockets; the ROS node runs the service socket, and the Modelica tool the client socket. This is separate from the actual model and control architecture - the interfaces are packaged as standalone components (a block in Modelica, and a node in ROS). This has two implications:
In ROS, it is possible to treat the Modelica model as a plant model, with no extra setup required to communicate with the model, apart from initializing the interface node, and listening/publishing to the appropriate topics. The interface node will both read the published values, and send it to the model, as well as publish the feedback values received from the model. Hence, all focus only need be placed on the interface node - the model can be treated as a black box, and the only parameters required are the node's port number, and the update rate of the node.
In Modelica, the block is structured as a discrete Sampler block; it is extended from the DiscreteMIMO interface, and has parameters for sample rate, number of inputs and outputs, among others. Pointing the client socket in Modelica can be done via additional parameter inputs, the hostname of the server socket's host machine, and the portNumber, of the server socket's port. Because it is a block, it is causal; because it runs a client socket, the block (and thus the model containing the block) cannot be run before the ROS architecture containing the server socket has been constructed. Finally, because the interface uses TCP/IP protocol, the order of messages is preserved, allowing the incoming control input to not be garbled and inaccurate. Finally, similar to in ROS, the block will not run any other part of the model apart from communicating with ROS. It also can be treated as a black box, with inputs from the model producing values meant as control input.
Separately, it is important to note that as the current version of modelica_bridge uses TCP sockets, and as ROS runs the server socket, the ROS interface node may require a SIGTERM to halt. This is because TCP server sockets generally listen for some time after connections have been closed, to ensure that there has been no queued up and waiting data; it does not affect the system at large, and so should not be a cause of concern.
Like any other ROS node, start the interface node via the following command (after starting the ROS Core):
rosrun modelica_bridge modbridge_node
As previously mentioned, the modbridge_node (the interface node) has two parameters: port_num_ and update_rate_. Set these via a launch file, or using the normal CLI commands. For more information about them, refer to the wiki. modbridge_node publishes the model's feedback to the topic /feedback_values, and takes input from the ROS system by reading from topic /control_values.
For a general idea on how to use the complement ROS_Sampler block in ROS_Bridge, view the example below.
Two Spring-Damper System Example
Within the ROS_Bridge Modelica package is an example called the TwoSpringDamperJoytickControl.mo model. This model uses a joystick, read by ROS's joy_node, to set the desired steady-state positions of the two springs, via a proportional control mechanism implemented in ROS. The communication is done via modbridge_node. The following assumes one is comfortable using the joy_node of the joy package - visit the wiki first otherwise.
In order to run this example model, one requires the ROS node architecture - this is available in a separate package, known as modelica_bridge_examples. Currently, it is only possible to build from source, via the following code:
git clone https://github.com/ModROS/modelica_bridge_examples.git ~/catkin_ws/src/modelica_bridge_examples
Build with catkin_make as usual.
Within modelica_bridge_examples are the nodes for running the ROS system along with the Modelica model - the nodes and launch file to provide the input to the entire spring-damper system. Looking at the model itself, pictured below, it is constructed from the Modelica Standard Library (version 3.2.2), consisting of the spring-damper and mass components of the Mechanical.Translational sub-package. Each mass, mounted to a spring, is subject to an external force; this force serves as the driving force that settles the position of the mass. The magnitude of the force is given by the output of a control block, and the input of said block are the positions of the masses.
This control block is the ROS_Sampler interface block provided by the ROS_Bridge Modelica package. The parameters of the block are shown in the image below - they consist of the number of inputs and outputs, nin and nout; the samplePeriod and the startTime of the sampling function; and the portNumber and hostName of the ROS server socket.
The values of nin and nout are important. The modbridge_node does not limit the number of control values sent from ROS to what is desired by the model; instead, it is the sampling block ROS_Sampler that does so. When the number of incoming values is too high, it will only read nout number of values; if the number is too low, it will zero-pad or last-provided-value-pad the control input to nout - number of incoming ROS input values, such that the model receives the nout values required.
Furthermore, samplePeriod represents the amount of simulation time to occur between each sample period. Because it is likely the simulation time of the model will not match the machine time (real time), it's highly recommended to run the model in real-time, with fixed solver step sizes.
Before simulating the example, the ROS architecture, provided by modelica_bridge_examples, must be started, otherwise a port-binding error will occur. Do so by running roslaunch modelica_bridge_examples two_springs_example.launch in the terminal. This will start the ROS core, the modbridge_node, two extra nodes for dictating control and input to the model, and the joy_node. Visualizing the node network produces this image:
The flow of information through the system is as follows:
The joy_node reads the input from the joystick.
The teleop node scales and modifies the joystick input into what becomes the desired model input.
The controller node reads from the /feedback_values topic, which contains the model's state values; it also reads the published model input coming from the teleop node. Using a simple proportional gain error controller, it calculates the required control values, and publishes this to the /control_values topic, to be read by the interface node.
modbridge_node reads from the /control_values topic and sends the queued values to the model.
Running rostopic echo /control_values shows that all 8 axes of the joystick, a different control value is being produced. However, only two values are being published on the /feedback_values topic; furthermore, the simulation log from the Modelica tool will only indicate 2 values being read. This is a result of what was said earlier - the ROS_Sampler block will only read nout values; since the default value of nout is 2, only two will be read.
As a separate trial, add another identical spring-damper system to the model, increase the values of nin and nout to 3, and connect the model together - the control block should start reading the third incoming value.
For more information, visit the wiki. If you'd like to add to the modelica_bridge_examples package, open a pull request here; add your associated Modelica code here.